package com.kevin.codec;

import com.kevin.constant.ReqType;
import com.kevin.core.Header;
import com.kevin.core.RpcProtocol;
import com.kevin.core.RpcRequest;
import com.kevin.core.RpcResponse;
import com.kevin.serial.ISerializer;
import com.kevin.serial.SerializerManager;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import lombok.extern.slf4j.Slf4j;

import java.util.List;

@Slf4j
public class RpcDecoder extends ByteToMessageDecoder {


    @Override
    protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List<Object> list) throws Exception {

        short magic = byteBuf.readShort();
        byte serialCode = byteBuf.readByte();
        byte reqTypeCode = byteBuf.readByte();
        long sessionId = byteBuf.readLong();
        int length = byteBuf.readInt();

        if(byteBuf.readableBytes()<length){
            log.error("消息不完整");
        }
        byte[] data = new byte[length];
        byteBuf.readBytes(data);

        Header header = new Header(magic,serialCode,reqTypeCode,sessionId,length);

        //根据不同的请求类型做不同的处理
        ReqType reqType = ReqType.getReqTypeByCode(reqTypeCode);
        ISerializer serializer = SerializerManager.getSerializer(serialCode);
        switch (reqType){
            case REQ_REQUERST:

                RpcRequest rpcRequest = serializer.deSerialize(data, RpcRequest.class);
                log.info("RpcDecoder log:{}",rpcRequest.toString());
                RpcProtocol<RpcRequest> requestRpcProtocol = new RpcProtocol<>();
                requestRpcProtocol.setHeader(header);
                requestRpcProtocol.setContent(rpcRequest);
                list.add(requestRpcProtocol);
                break;
            case REQ_RESPONSE:
                RpcResponse rpcResponse = serializer.deSerialize(data, RpcResponse.class);
                RpcProtocol<RpcResponse> rpcResponseRpcProtocol = new RpcProtocol<>();
                rpcResponseRpcProtocol.setHeader(header);
                rpcResponseRpcProtocol.setContent(rpcResponse);
                list.add(rpcResponseRpcProtocol);
                break;
            case REQ_PING:
                break;

            case REQ_PONG:
                break;

                default:
                    break;

        }

    }
}
